/* 
 * File:   parentChildComm.cpp
 * Author: Stephen Durfey and Steve Gal
 *
 * Created on September 20, 2008, 11:09 AM
 */

#include <iostream>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <time.h>
#include <string.h>
#include <cstdlib>
#include <stdlib.h>

using namespace std;


int main(int argc, char** argv) 
{
      string child_start_time, 
             child_end_time,
             parent_start_time, 
             parent_end_time;
      
      char bufferChild[2] = {'1'};
      char bufferParent[2] = {'1'};
      int the_pipe[2], parent_pipe[2];
      int randNum = atoi(argv[1]);
      
      string procOrder = argv[2];
        
      time_t the_time;
      pid_t child;
      
      pipe(parent_pipe);
      
      
      srand(NULL);
      
      if(pipe(the_pipe) == 0)   //checks to ensure the pipe was created
      {
         child = fork();//string procOrder = "parent";
         
         if(child != -1)   //checks to make sure the fork worked
         {
             
            if(child == 0)  //child process
            {
                time(&the_time);
                child_start_time = ctime(&the_time);
                
                if(procOrder == "parent") //if parent goes first, wait for a signal
                {
                    while(randNum > 0)
                    {
                        read(the_pipe[0], bufferChild, 20);
                        cout << "Child: " << rand() << endl;
                     
                        write(parent_pipe[1], bufferChild, strlen(bufferChild));
                     
                        randNum--;
                    }
                 }
                else  //else go ahead and print first and send signal to parent
                {
                    while(randNum > 0)
                    {
                        cout << "Child: " << rand() << endl;
                        write(parent_pipe[1], bufferChild, strlen(bufferChild));
                        read(the_pipe[0], bufferChild, 20);
                        
                        randNum--;
                    }
                }
                
                time(&the_time);
                child_end_time = ctime(&the_time);
                
                cout << "Child " << getpid() << " Begin " << child_start_time << " End " << child_end_time << endl;
             }
             else
             {
                time(&the_time);
                parent_start_time = ctime(&the_time);
                
                if(procOrder == "child")  //if child first, wait for signal
                {
                    while(randNum > 0)
                    {
                        read(parent_pipe[0], bufferParent, 20);
                        cout << "Parent: " << rand() << endl;
                        write(the_pipe[1], bufferParent, strlen(bufferParent));
                    
                        randNum--;
                    }
                }
                else
                {
                    while(randNum > 0)
                    {
                    
                        cout << "Parent: " << rand() << endl;
                    
                        write(the_pipe[1], bufferParent, strlen(bufferParent));
                        read(parent_pipe[0], bufferParent, 20);
                     
                     
                        randNum--;
                    }
                }
                
                time(&the_time);
                child_end_time = ctime(&the_time);
                
                cout << "Parent " << getpid() << " Begin " << parent_start_time << " End " << parent_end_time << endl;
                
             }
          }
         else
             cerr << "didnt fork\n";
      }
      else 
        cerr << "didnt pipe\n";
      
      return (EXIT_SUCCESS);
}

